#ifndef BPE_COLLISION_WORLD_H
#define BPE_COLLISION_WORLD_H

#include <boost/multi_array.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>
#include <queue>
#include "BPECollisionData.h"
#include "../BPEMath/BPEVector3d.h"

#include "BPECollisionWorldArea.h"
#include "BPEBoundingBox.h" 

using namespace std;
using namespace boost;

class BPECollisionWorld{

private:	
	//3 dimensional array
	multi_array<shared_ptr<BPECollisionWorldArea>, 3> bpeAreaCubes;
	int xArraySize;
	int yArraySize;
	int zArraySize;

	vector<	shared_ptr<BPEBoundingShape>	> bpeBoundShapes;
	BPEPoint3d getAreaCode(BPEPoint3d p);

	bool getCollisionResults(BPEBoundingShape *first, BPEBoundingShape *second,BPEVector3d &normal, double &depth );


	void recalculateAreaCodes(const vector<bool> &willRecalculate);

	void getCollisionPairs(vector<BPECollisionData> &collPairs);
	
	BPEVector3d getCollisionNormal(BPEBoundingShape* first,BPEBoundingShape* second);

	void getAreasAndEdgesOfCollisionObjects(BPEBoundingShape* first,BPEBoundingShape* second, vector3df *edges1 , vector3df *edges2,queue<plane3d<f32>> &objPlanes1, queue<plane3d<f32>> &objPlanes2);
	
public:
	BPECollisionWorld();
	BPECollisionWorld(BPEPoint3d worldEdge1, BPEPoint3d worldEdge2);

	void updateBoundingBox(const int &code, const BPEPoint3d &center, const BPEVector3d &rotation);

	shared_ptr<BPEBoundingShape> getBoundingBox(const int& objCode);

	void addBoundingShape(shared_ptr<BPEBoundingShape> &bShape);
	void collisionRoutine(vector<bool> onMove, vector<BPEVector3d> speeds ,  vector<BPECollisionData> &collisionPairs, vector<BPEVector3d> &fixSpeeds);
	//void collisionRoutineNormalVectorPhase(vector<BPECollisionData> &collisionPairs);
};




#endif